/*
 * Copyright (c) 2017,安徽皖通科技股份有限公司 All rights reserved.
 */

package com.wttech.dzzf.process.service.upload;

import cn.com.taiji.sdk.model.comm.protocol.AbstractSdtsRequest;
import com.wttech.dzzf.process.constant.ExecuteTable;
import com.wttech.dzzf.process.dao.TransferUserInfoDao;
import com.wttech.dzzf.process.service.base.BaseInfoService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.wttech.dzzf.process.constant.UserConstants.DEFAULT_PROCESS_NUM;

/**
 * 向部中心上传生产数据
 *
 * @author MaShibo
 * @date 2017/12/11.
 */
@Service
public class UploadProductDataService {

	private static final Logger LOGGER = LoggerFactory.getLogger(UploadProductDataService.class);

	/**
	 * 待上传数据表
	 */
	private List<ExecuteTable> executeTables;

	@Resource
	private TransferUserInfoDao transferUserInfoDao;

	@Resource
	private ThreadPoolTaskExecutor executor;

	@Resource
	private UploadSingleDataService uploadSingleDataService;

	@Resource
	private UploadMonitorService uploadMonitorService;

	@Resource
	private BaseInfoService baseInfoService;

	private boolean isRunning = false;

	private void upload() {
		if (CollectionUtils.isEmpty(executeTables)) {
			LOGGER.warn("未指定需要上传的数据");
			return;
		}
		List<String> tableNameList = executeTables.stream().map(ExecuteTable::getTableName).collect(Collectors.toList());
		String tableNames = StringUtils.join(tableNameList, ", ");
		LOGGER.info("待上传的数据表：{}", tableNames);
		executeTables.forEach(this::uploadSingleExecuteTable);
		LOGGER.info("上传完成");
		executor.shutdown();
	}

	private void uploadSingleExecuteTable(ExecuteTable table) {
		int totalNum = transferUserInfoDao.queryUserInfoCount(table.getTableName());
		LOGGER.info("{}共{}条数据待处理...", table.getTableName(), totalNum);
		if (totalNum <= 2 * DEFAULT_PROCESS_NUM) {
			uploadSingleDataService.uploadSingleQuery(table, totalNum);
			LOGGER.info("数据上传完成");
			return;
		}
		while (true) {
			List<? extends AbstractSdtsRequest> infos = transferUserInfoDao.queryUseriInfoRecord(table.getTableName(), table.getRequestType(),
					1, DEFAULT_PROCESS_NUM);;
			if (CollectionUtils.isEmpty(infos)){
				LOGGER.info("数据上传完毕");
				return;
			}
			List<Future<Void>> futures = new ArrayList<>(infos.size());
			infos.forEach(info -> futures.add(executor.submit(() -> {
				uploadSingleDataService.uploadSdtsInfo(info, table,false);
				return null;
			})));
			baseInfoService.getFutureResult(futures);
		}
	}


	@Scheduled(fixedDelay = 1000 * 20)
	public void monitor() {
		if (!isRunning || CollectionUtils.isEmpty(executeTables)) {
			return;
		}
		executeTables.forEach(table -> uploadMonitorService.monitor(table));
	}

	private void setExecuteTables(List<ExecuteTable> executeTables) {
		this.executeTables = executeTables;
	}

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		UploadProductDataService service = context.getBean(UploadProductDataService.class);
		if (args != null) {
			List<ExecuteTable> executeTables = Arrays.stream(args)
					.filter(StringUtils::isNotBlank)
					.map(storeName -> Arrays.stream(ExecuteTable.values())
							.filter(table -> table.getStorePath().equalsIgnoreCase(storeName))
							.findFirst()
							.orElse(null))
					.filter(Objects::nonNull)
					.collect(Collectors.toList());
			service.setExecuteTables(executeTables);
		}
		service.isRunning=true;
		service.upload();
	}


}
